package com.qualityeclipse.genealogy.editor;

import java.util.*;

import org.eclipse.gef.*;
import org.eclipse.jface.viewers.*;

/**
 * A selection listener that prevents nested parts from being selected
 * when their parent or grandparent part is selected.
 * Unfortunately this approach allows the unmodified selection to be 
 * broadcast and then broadcasts the modified selection afterward.
 */
class SelectionModificationChangeListener
	implements ISelectionChangedListener
{
	private final GraphicalViewer viewer;

	SelectionModificationChangeListener(GraphicalViewer viewer) {
		this.viewer = viewer;
	}

	/**
	 * Cycle through the each of the selected EditParts 
	 * and removes any which have a selected ancestor.
	 */
	public void selectionChanged(SelectionChangedEvent event) {
		
		// Build a collection of originally selected parts
		// and a collection from which nested parts are removed
		
		List<?> oldSelection = ((IStructuredSelection) event.getSelection()).toList();
		final List<Object> newSelection = new ArrayList<Object>(oldSelection.size());
		newSelection.addAll(oldSelection);

		// Cycle through all selected parts and remove nested parts
		// which have a parent or grandparent part that is selected
		
		EditPart root = viewer.getRootEditPart();
		Iterator<Object> iter = newSelection.iterator();
		while (iter.hasNext()) {
			EditPart part = (EditPart) iter.next();
			while (part != root) {
				part = part.getParent();
				if (newSelection.contains(part)) {
					iter.remove();
					break;
				}
			}
		}

		// If the new selection is smaller than the original selection
		// then modify the current selection
		
		if (newSelection.size() < oldSelection.size()) {
			viewer.getControl().getDisplay().asyncExec(new Runnable() {
				public void run() {
					viewer.setSelection(new StructuredSelection(newSelection));
				}
			});
		}
	}
}